/* CsJni - .NET / Java Bridge
 * 
 * Copyright 2010 Robert E. Burke Licensed under the Apache License, Version 
 * 2.0 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
 * law or agreed to in writing, software distributed under the License is 
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;

namespace CsJni
{
    [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")]
    [StructLayout(LayoutKind.Explicit)]
    public struct JValue
    {
#pragma warning disable 0414 // assigned but not used - is used, passed to JVM
        // NOTE: Fields incorrectly detected by FxCop as unused.
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jboolean */ private byte z;
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jbyte */ private byte b;
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jchar */ private char c;
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jshort */ private short s;
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jint */ private int i;
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jlong */ private long j;
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jfloat */ private float f;
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
        [FieldOffset(0)] /* jdouble */ private double d;
        [FieldOffset(0)] /* jobject */ private IntPtr l;

        public void AssignBooleanValue(bool value)
        {
            this.z = JBooleanConverter.To(value);
        }

        public void AssignByteValue(byte value)
        {
            this.b = value;
        }

        public void AssignCharValue(char value)
        {
            this.c = value;
        }

        public void AssignShortValue(short value)
        {
            this.s = value;
        }

        public void AssignIntValue(int value)
        {
            this.i = value;
        }

        public void AssignLongValue(long value)
        {
            this.j = value;
        }

        public void AssignFloatValue(float value)
        {
            this.f = value;
        }

        public void AssignDoubleValue(double value)
        {
            this.d = value;
        }

        public void AssignObjectValue(JniObject value)
        {
            this.l = (value == null) ? IntPtr.Zero : value.Handle;
        }

        public void AssignStringValue(JniEnvironment environment, string value)
        {
            this.l = (value == null) ? IntPtr.Zero : JniString.NewStringCore(environment, value); ;
        }

        public void Free(JniEnvironment environment)
        {
            if (this.l != IntPtr.Zero && environment != null)
            {
                JniEnvironment.Functions.DeleteLocalRef(environment.Handle, this.l);
                // EXCEPTION CHECK: Do nothing, this method safe to call while exception is pending, does
                // not raise additional exceptions.
                this.l = IntPtr.Zero;
            }
        }
#pragma warning restore 0414
    }
}
